package com.example.kuaizu.service.imp;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.example.kuaizu.mapper.ProjectMapper;
import com.example.kuaizu.mapper.UserMapper;
import com.example.kuaizu.pojo.*;
import com.example.kuaizu.pojo.ov.ProjectOv;
import com.example.kuaizu.pojo.ov.UserProofOv;
import com.example.kuaizu.service.InUserService;
import com.example.kuaizu.utils.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import kuaizu.common.constp.KuaiZuConst;
import kuaizu.common.exception.MassageException;
import kuaizu.common.tablepojo.School;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static kuaizu.common.constp.KuaiZuConst.ERROR;

/**
 * @author xiaokai
 * 用户相关业务逻辑
 */
@Service
public class UserService implements InUserService {
    private static final Logger log = LoggerFactory.getLogger(UserService.class);
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WxRequestUtils wxRequestUtils;
    @Autowired
    private ProjectMapper projectMapper;
    //线程池
    @Autowired
    private ThreadPoolTaskExecutor customThreadPool;

    @Autowired
    private FileStorageService fileStorageService;//注入实列
    @Autowired
    private FileUtils fileUtils;
    @Override
    @Transactional
    public int userRegion(UserProfile user) {
        //查询用户是否存在
        UserProfile userinfo = userMapper.selectByOpenId(user.getOpenid());
        //保存到数据库
        if (userinfo != null) {
            throw new MassageException(ERROR, "你已经注册过了,请勿重复注册");
        }
        //
        //创建一个线程
        //获取当前时间戳
        //customThreadPool.execute(() -> {
        //    //先查询数据库是否有这个学校的专业信息
        //    Integer school = userMapper.selectSchoolMajor(user.getSchool(), user.getMajor());
        //    if (school == null) {
        //        log.info("学校和专业不存在,添加学校和专业");
        //        userMapper.insertMajor(user.getSchool(), user.getMajor());
        //    }
        //});
        return userMapper.insertUser(user);
        //return 1;

    }

    /**
     * 登陆
     *
     * @param jsCode 用户的唯一id
     */
    @Override
    @Transactional
    public UserProfile login(String jsCode) throws Exception {
        //调用WxRequestUtils.getRequest(jsCode)获取openid
        String json = wxRequestUtils.getRequest(jsCode);
        //将字符串转成json对象
        // 创建 ObjectMapper 实例
        ObjectMapper objectMapper = new ObjectMapper();
        // 将 JSON 字符串转换为 Map 集合
        Map<String, Object> map = objectMapper.readValue(json, Map.class);
        //根据用户的appid查询用户信息
        System.out.println(map);

        if (map.get("errcode") != null) {
            if (map.get("errcode").equals(KuaiZuConst.LOGIN_Error_NOJSCODE)) {
                //表示无效的jscode需要重新登陆获取
                System.out.println("无效的jscode");
                throw new Exception("无效的jscode,请重新登陆");
            }
            throw new MassageException(ERROR, "服务异常,重新登陆");
        }
        System.out.println(map);
        UserProfile user = userMapper.selectByOpenId(map.get("openid").toString());
        if (user == null) {
            throw new MassageException(ERROR, "你是不是没有注册吖,先注册一下好不好");
            //用户不存在,进行注册
            //UserProfile xinuser = new UserProfile();
            //xinuser.setOpenid(map.get("openid").toString());
            ////xinuser.setAccessToken(map.get("session_key").toString());
            //xinuser.setCreatedAt(DateFromUtils.getNowDate());//创建时间
            ////xinuser.setUpdatedate(DateFromUtils.getNowDate());
            ////添加用户信息
            //log.info("用户不存在,进行注册");
            //log.info("用户信息:{}", xinuser);
            //userMapper.insertUser(xinuser);
            //return xinuser;
        } else {
            //用户存在,进行登录
            //user.setAccessToken(map.get("session_key").toString());
            return user;
        }
    }

    //更新个人信息
    @Override
    @Transactional
    public int updateUser(UserProfile user) {
        //user.setUpdatedate(DateFromUtils.getNowDate());
        log.info("修改的学生信息:{}", user);
        Map<String, Object> map = ThreadLocalUtil.get();
        user.setCoverImage(null);
        user.setAvatarUrl(null);
        user.setOpenid(map.get("openid").toString());
        LambdaUpdateWrapper<UserProfile> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(UserProfile::getOpenid, user.getOpenid());
        //int i = userMapper.updateUser(user);
        //System.out.println(i + "---影响条数");
        return userMapper.update(user, updateWrapper);
    }


    //上传头像
    @Override
    @Transactional
    public String uploadAvatar(MultipartFile file) {
        //设置当前日期格式
        String pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd/"));
        FileInfo fileInfo = fileStorageService.of(file)
                .setPath(pathName) //保存到相对路径下，为了方便管理，不需要可以不写
                .upload();  //将文件上传到对应地方
        log.info("文件上传成功，文件信息：{}", fileInfo);
        //更新数据库的头像信息
        Map<String, Object> map = ThreadLocalUtil.get();
        UserProfile user = userMapper.selectByOpenId(map.get("openid").toString());
        //获取原来的头像信息
        if (user != null) {
            //删除原来的头像信息
            log.info(fileUtils.deleteFile(user.getAvatarUrl()));
            //重新获取token
        }
        userMapper.updateUserAvatar(fileInfo.getPath() + fileInfo.getFilename(), map.get("openid").toString());
        log.info("存储的图片路径：{}", fileInfo.getPath() + fileInfo.getFilename());
        return fileInfo.getPath() + fileInfo.getFilename();
    }


    //查询用户信息
    @Override
    @Transactional
    public UserProfile selectUserByAppid(String openid) {
        return userMapper.selectUserByAppid(openid);
    }

    //上传背景图
    @Override
    @Transactional
    public String uploadBg(MultipartFile file) {
        FileInfo fileInfo = upImg(file);
        //更新数据库的头像信息
        Map<String, Object> map = ThreadLocalUtil.get();
        UserProfile user = userMapper.selectByOpenId(map.get("openid").toString());
        //获取原来的头像信息
        if (user != null) {
            //删除原来的头像信息
            log.info(fileUtils.deleteFile(user.getCoverImage()));
            //重新获取token
        }
        userMapper.uploadBg(fileInfo.getPath() + fileInfo.getFilename(), map.get("openid").toString());
        log.info("存储的图片路径：{}", fileInfo.getPath() + fileInfo.getFilename());
        return fileInfo.getPath() + fileInfo.getFilename();
    }

    //查询学校
    @Override
    @Transactional
    public List<School> selectSchool(String school) {
        return userMapper.selectSchool(school);
    }


    //上传学生证
    @Override
    @Transactional
    public String uplStudentImg(MultipartFile file) {
        if (file == null) {
            throw new MassageException("文件不能为空");
        }
        FileInfo fileInfo = upImg(file);
        String url = fileInfo.getPath() + fileInfo.getFilename();
        Map<String, Object> map = ThreadLocalUtil.get();
        String open = map.get("openid").toString();
        //判断数据库是否有这条数据
        Certification certification = userMapper.selectByOpenidProofInfo(open);
        if (certification != null) {
            //修改数据库的数据
            userMapper.updateUserProofImg(open, url);
        } else {
            certification = new Certification();
            certification.setOpenId(open);
            certification.setUserPhoto(fileInfo.getPath());
            certification.setCreatedAt(new Date());
            //新增数据
            userMapper.InsterUserProof(certification);
        }

        return url;
    }

    //修改审核状态
    @Override
    @Transactional
    public void reviewstudent(ReviewParam reviewParam) {
        Certification certification = userMapper.selectByOpenidProofInfo(reviewParam.getOpenId());
        //判断审核状态
        if (reviewParam.getProofStart()) {
            //是本校的人
            updateProofStart(reviewParam, "审核成功", KuaiZuConst.CHECKPASS, certification);
        } else {
            updateProofStart(reviewParam, "审核失败", KuaiZuConst.CHECKNO, certification);
        }

    }

    //查询指定学校的审核信息
    @Override
    @Transactional
    public AjaxResponse queryStudent(Integer id) {
        List<UserProofOv> userProofOvs = userMapper.querStudnet(id);
        //根据状态划分
        Map<Integer, List<UserProofOv>> groupMap = userProofOvs.stream()
                .collect(Collectors.groupingBy(UserProofOv::getUserProofStart));
        return AjaxResponse.success("查询成功", userProofOvs);

    }

    @Override
    @Transactional
    public AjaxResponse getPhone(Map<String, String> map) {
        return AjaxResponse.success(wxRequestUtils.getPhoneNumber(map).getPhone_info());
    }

    //注销用户
    @Transactional
    @Override
    public void userOffline(UpdateUserInfoParam userOfflineParam) {
        //根据id查询是否有这个用户
        UserProfile userProfile = userMapper.selectByOpenId(userOfflineParam.getOpenId());
        if (ObjectUtils.isNull(userProfile)) {
            throw new MassageException("用户不存在");
        }
        //根据openid查找是否还有对应的项目
        String openId = userOfflineParam.getOpenId();
        List<ProjectOv> prsoajtLcen = projectMapper.SelectProjectList(openId);
        if (!CollUtil.isEmpty(prsoajtLcen)) {
            throw new MassageException("该用户有项目，不能注销");
        }
        //删除加入项目表中的用户信息
        projectMapper.delectProjectReviewInfo(openId);
        //删除用户认证信息表中的数据
        userMapper.DelectCertificationInfo(openId);
        //注销用户
        userMapper.userOffline(openId);
    }

    //更新用户id
    @Override
    @Transactional
    public String updateUserToken(UpdateUserTokenParam param) {
        //根据id和openid去数据库查询信息
        UserProfile userProfile = userMapper.selectUserByIdAndOpenId(param.getId(), param.getOpenid());
        //使用hutool包判断对象是否为null
        if (ObjectUtils.isNull(userProfile)) {
            throw new MassageException("用户不存在");
        }
        //将对象转成map集合
        ObjectMapper objectMapper = new ObjectMapper();
        Map map = objectMapper.convertValue(userProfile, Map.class);
        String token = JwtUtils.genToken(map);
        return token;
    }


    private void updateProofStart(ReviewParam reviewParam, String s, Integer start, Certification certification) {
        String str = "{id->" + reviewParam.getReviewId() +
                "name->" + reviewParam.getName() +
                "proof->" + s +
                "tetx->" + reviewParam.getText() +
                "}";
        //设置审核状态
        certification.setCertificationInfo(str);
        certification.setUpdatedAt(new Date());
        //修改审核数据表
        userMapper.updateUserProofuserInfoByOpenId(reviewParam.getOpenId(), certification);
        //修改用户的状态
        userMapper.updateUserProoStart(start, reviewParam.getOpenId());
    }

    private FileInfo upImg(MultipartFile file) {
        String pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd/"));
        FileInfo fileInfo = fileStorageService.of(file)
                .setPath(pathName) //保存到相对路径下，为了方便管理，不需要可以不写
                .upload();  //将文件上传到对应地方
        log.info("文件上传成功，文件信息：{}", fileInfo);
        return fileInfo;
    }
}
